using SG3L_RAG.Application.Interfaces;
using SG3L_RAG.Domain.Entities;
using SG3L_RAG.Domain.Repositories;

namespace SG3L_RAG.Application.Services
{
    public class DocumentService : IDocumentService
    {
        private readonly IRepository<Document> _documentRepository;

        public DocumentService(IRepository<Document> documentRepository)
        {
            _documentRepository = documentRepository;
        }

        public async Task<Document?> GetByIdAsync(Guid id)
        {
            return await _documentRepository.GetByIdAsync(id);
        }

        public async Task<IEnumerable<Document>> GetAllAsync()
        {
            return await _documentRepository.GetAllAsync();
        }

        public async Task<Document> CreateAsync(string name, string type, Guid uploaderId, string status, string permission)
        {
            var document = Document.Create(name, type, uploaderId, status, permission);
            await _documentRepository.AddAsync(document);
            return document;
        }

        public async Task UpdateAsync(Document document)
        {
            await _documentRepository.UpdateAsync(document);
        }

        public async Task DeleteAsync(Guid id)
        {
            await _documentRepository.DeleteAsync(id);
        }

        public async Task<IEnumerable<Document>> GetByUploaderIdAsync(Guid uploaderId)
        {
            var documents = await _documentRepository.GetAllAsync();
            return documents.Where(d => d.UploaderId == uploaderId);
        }

        public async Task<IEnumerable<Document>> GetByTypeAsync(string type)
        {
            var documents = await _documentRepository.GetAllAsync();
            return documents.Where(d => d.Type == type);
        }

        public async Task<IEnumerable<Document>> GetByStatusAsync(string status)
        {
            var documents = await _documentRepository.GetAllAsync();
            return documents.Where(d => d.Status == status);
        }

        public async Task<IEnumerable<Document>> SearchByTitleAsync(string title)
        {
            var documents = await _documentRepository.GetAllAsync();
            return documents.Where(d => d.Name.Contains(title, StringComparison.OrdinalIgnoreCase));
        }

        public async Task<IEnumerable<Document>> GetPublicDocumentsAsync()
        {
            var documents = await _documentRepository.GetAllAsync();
            return documents.Where(d => d.IsPublic());
        }

        public async Task ProcessDocumentAsync(Guid documentId)
        {
            var document = await _documentRepository.GetByIdAsync(documentId);
            if (document != null)
            {
                document.SetStatus("processed");
                await _documentRepository.UpdateAsync(document);
            }
        }

        public async Task<List<Document>> BatchCreateAsync(List<(string name, string type, Guid uploaderId, string status, string permission)> docs)
        {
            var documents = Document.BatchCreate(docs);
            await _documentRepository.AddRangeAsync(documents);
            return documents;
        }

        public async Task SetPermissionAsync(Guid documentId, string permission)
        {
            var document = await _documentRepository.GetByIdAsync(documentId);
            if (document != null)
            {
                document.SetPermission(permission);
                await _documentRepository.UpdateAsync(document);
            }
        }

        public async Task SetStatusAsync(Guid documentId, string status)
        {
            var document = await _documentRepository.GetByIdAsync(documentId);
            if (document != null)
            {
                document.SetStatus(status);
                await _documentRepository.UpdateAsync(document);
            }
        }
    }
}
